from bct.tools.common.bct4.base_dto import JsonDTO


class PartyMargin(JsonDTO):
    # 交易对手id
    party_id: str
    # 计算日期yyyy-mm-dd
    valuation_date: str
    # 合约价值
    trade_value: int = 0
    # 折算后合约价值
    discount_trade_value: int = 0
    # 初始保障金额
    initial_margin_amount: int = 0
    # 维持保障金额.单一标的合约
    single_condition_amount: int = 0
    # 维持保障金额
    mix_condition_amount: int = 0
    # 维持保障金额.单一标的合约
    single_margin_amount: int = 0
    # 维持保障金额.单一标的保障组合
    combo_margin_amount: int = 0

    def to_dict(self):
        return {
            "partyId": self.party_id,
            "valuationDate": self.valuation_date,
            "tradeValue": self.trade_value,
            "discountTradeValue": self.discount_trade_value,
            "initialMarginAmount": self.initial_margin_amount,
            "singleConditionAmount": self.single_condition_amount,
            "mixConditionAmount": self.mix_condition_amount,
            "singleMarginAmount": self.single_margin_amount,
            "comboMarginAmount": self.combo_margin_amount
        }


class PartyMarginDetail(JsonDTO):
    # 交易对手id
    party_id: str
    # 交易对手
    party_name: str
    # 计算日期yyyy-mm-dd
    valuation_date: str
    # 交易ID
    trade_id: str
    # 起始日yyyy-mm-dd
    effective_date: str
    # 期权类型
    product_type: str
    # 合约状态
    lcm_event_type: str
    # 名义本金
    notional_amount: str
    # 标的物ID
    underlyer_instrument_id: str
    # 保证金计算模式
    margin_rule: str
    # 单笔PV
    origin_price: int
    # 压力VaR单笔PV.单一标的合约
    single_price: int
    # 压力VaR单笔PV
    margin_price: int
    # spot
    spot: int
    # vol
    vol: int
    # r
    r: int
    # q
    q: int
    # 初始保证金比例
    initial_margin_rate: int
    # 初始保障金额
    initial_margin_amount: int
    # 合约价值
    trade_value: int = 0
    # 合约价值折算率
    trade_discount_rate: int = 0
    # 折算后合约价值
    trade_value_discounted: int = 0
    # 维持保障金额.单一标的合约(￥，不含合约价值)
    single_margin: int = 0
    # 维持保障金额.单一标的合约（￥，含合约价值）
    single_margin_contain_trade_value: int = 0
    # 维持保障金额（￥，不含合约价值）
    maintenance_margin: int = 0
    # 维持保障金额（￥，含合约价值）
    maintenance_margin_contain_trade_value: int = 0

    def to_dict(self):
        return {
            "partyId": self.party_id,
            "valuationDate": self.valuation_date,
            "tradeValue": self.trade_value,
            "initialMarginAmount": self.initial_margin_amount,
            "partyName": self.valuation_date,
            "tradeId": self.trade_id,
            "effectiveDate": self.effective_date,
            "productType": self.product_type,
            "notionalAmount": self.notional_amount,
            "lcmEventType": self.lcm_event_type,
            "underlyerInstrumentId": self.underlyer_instrument_id,
            "marginRule": self.margin_rule,
            "originPrice": self.origin_price,
            "singlePrice": self.single_price,
            "marginPrice": self.margin_price,
            "spot": self.spot,
            "vol": self.vol,
            "r": self.r,
            "q": self.q,
            "initialMarginRate": self.initial_margin_rate,
            "tradeDiscountRate": self.trade_discount_rate,
            "tradeValueDiscounted": self.trade_value_discounted,
            "singleMargin": self.single_margin,
            "singleMarginContainTradeValue": self.single_margin_contain_trade_value,
            "maintenanceMargin": self.maintenance_margin,
            "maintenanceMarginContainTradeValue": self.maintenance_margin_contain_trade_value
        }


def to_party_margin(party: dict):
    r = PartyMargin()
    r.party_id = party.get("partyId")
    r.valuation_date = party.get("valuationDate")
    r.trade_value = party.get("tradeValue")
    r.discount_trade_value = party.get("discountTradeValue")
    r.initial_margin_amount = party.get("initialMarginAmount")
    r.single_condition_amount = party.get("singleConditionAmount")
    r.mix_condition_amount = party.get("mixConditionAmount")
    r.single_margin_amount = party.get("singleMarginAmount")
    r.combo_margin_amount = party.get("comboMarginAmount")
    return r


def to_party_margin_detail(party_detail: dict):
    r = PartyMarginDetail()
    r.party_id = party_detail.get("partyId")
    r.valuation_date = party_detail.get("valuationDate")
    r.party_name = party_detail.get("partyName")
    r.trade_id = party_detail.get("tradeId")
    r.effective_date = party_detail.get("effectiveDate")
    r.product_type = party_detail.get("productType")
    r.notional_amount = party_detail.get("notionalAmount")
    r.lcm_event_type = party_detail.get("lcmEventType")
    r.underlyer_instrument_id = party_detail.get("underlyerInstrumentId")
    r.margin_rule = party_detail.get("marginRule")
    r.origin_price = party_detail.get("originPrice")
    r.single_price = party_detail.get("singlePrice")
    r.margin_price = party_detail.get("marginPrice")
    r.spot = party_detail.get("spot")
    r.vol = party_detail.get("vol")
    r.r = party_detail.get("r")
    r.q = party_detail.get("q")
    r.initial_margin_rate = party_detail.get("initialMarginRate")
    r.initial_margin_amount = party_detail.get("initialMarginAmount")
    r.trade_value = party_detail.get("tradeValue")
    r.trade_discount_rate = party_detail.get("tradeDiscountRate")
    r.trade_value_discounted = party_detail.get("tradeValueDiscounted")
    r.single_margin = party_detail.get("singleMargin")
    r.single_margin_contain_trade_value = party_detail.get("singleMarginContainTradeValue")
    r.maintenance_margin = party_detail.get("maintenanceMargin")
    r.maintenance_margin_contain_trade_value = party_detail.get("maintenanceMarginContainTradeValue")
    return r
